package network.impl;

import java.util.LinkedList;
import java.util.List;


import network.NetworkID;
import network.ServerNetworkListener;

import sharedNetwork.NetworkFlags;

public class NetServer implements ConnectionListener, ServerInputThreadListener {
	
	private List<ServerThread> threads;
	private ConnectionThread connectionThread;
	private List<ServerNetworkListener> listeners;

	public NetServer(int port) {
		threads = new LinkedList<ServerThread>();
		listeners = new LinkedList<ServerNetworkListener>();
		connectionThread = new ConnectionThread(port);
		connectionThread.addConnectionListener(this);
	}
	
	public void start() {
		connectionThread.start();
	}

	public synchronized void send(Object obj, NetworkID id) {
		int index = threads.indexOf(id);
		if(index != -1) {
			threads.get(index).send(obj);
		} //TODO: Add else as an exception
	}
	
	public synchronized void sendToAll(Object obj) {
		for (ServerThread thread : threads) {
			thread.send(obj);
		}
	}
	@Override
	public synchronized void newConnection(ServerThread serverThread) {
		threads.add(serverThread);
		for (ServerNetworkListener listener : listeners) {
			serverThread.addNetworkListener(listener);
		}
		serverThread.addServerInputThreadListener(this);
	}
	
	public void addNetworkListener(ServerNetworkListener listener) {
		listeners.add(listener);
	}

	@Override
	public synchronized void connectionLost(NetworkID id) {
		int index = threads.indexOf(id);
		if(index != -1) {
			threads.get(index).shutDown();
			threads.remove(index);
			System.out.println("Removed the disconnected client");
		} //TODO: Add else as an exception
	}

	@Override
	public synchronized void disconnect(NetworkID id) {
		send(NetworkFlags.DISCONNECTION_ACCEPTED, id);
		int index = threads.indexOf(id);
		if(index != -1) {
			threads.get(index).shutDown();
			threads.remove(index);
			System.out.println("Diconnecting the client");
		} //TODO: Add else as an exception
	}

	@Override
	public synchronized void disconnectionAccepted(NetworkID id) {
		int index = threads.indexOf(id);
		if(index != -1) {
			threads.get(index).shutDown();
			threads.remove(index);
			System.out.println("Diconnecting the client");
		} //TODO: Add else as an exception
	}
	
	public void shutDown() {
		disconnectClients();
		connectionThread.shutDown();
	}
	
	private void disconnectClients() {
		sendToAll(NetworkFlags.DISCONNECT);
	}
}